﻿using System;
using System.Data;
using System.Data.SqlClient;

namespace WithdrawMoneyFromAccount
{
    public class Program
    {
        public static void WithdrawMoney(SqlConnection dbCon, 
            string cardNumber, string cardPIN, decimal amount)
        {
            SqlTransaction withdrawTransaction = 
                dbCon.BeginTransaction(IsolationLevel.RepeatableRead);

            SqlCommand selectAccount = new SqlCommand();
            selectAccount.Connection = dbCon;
            selectAccount.Transaction = withdrawTransaction;
            selectAccount.CommandText =
                "SELECT * " + 
                "FROM CardAccounts " + 
                "WHERE CardNumber = @cardNumber";
            selectAccount.Parameters.Add("@cardNumber", cardNumber);

            SqlDataReader reader = selectAccount.ExecuteReader();
            using (reader)
            {
                if (reader.Read() == false)
                {
                    withdrawTransaction.Rollback();
                    throw new ArgumentException("Invalid card number.");
                }
                if ((string)reader["CardPIN"] != cardPIN)
                {
                    withdrawTransaction.Rollback();
                    throw new ArgumentException("Invalid PIN number.");
                }
                if ((decimal)reader["CardCash"] < amount)
                {
                    withdrawTransaction.Rollback();
                    throw new ArgumentException(
                        "You do not have enough money for that transaction.");
                }
            }

            SqlCommand withdrawCommand = new SqlCommand();
            withdrawCommand.Connection = dbCon;
            withdrawCommand.Transaction = withdrawTransaction;
            withdrawCommand.CommandText =
                "UPDATE CardAccounts " + 
                "SET CardCash = CardCash - @withdraw " + 
                "WHERE CardNumber = @cardNumber";
            withdrawCommand.Parameters.Add("@cardNumber", cardNumber);
            withdrawCommand.Parameters.Add("@withdraw", amount);
            withdrawCommand.ExecuteNonQuery();

            withdrawTransaction.Commit();
        }

        public static void Main()
        {
            SqlConnection dbCon = new SqlConnection(
                "Server=.\\SQLEXPRESS; Database=atm; Integrated Security=true");
            dbCon.Open();
            using (dbCon)
            {
                WithdrawMoney(dbCon, "1785471147", "3445", 200);
            }
        }
    }
}
